package com.example.mytips.structure;

import com.example.mytips.utils.PathUtil;
import com.example.mytips.utils.ReadFileUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowFactory;
import com.intellij.ui.JBColor;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.components.JBList;
import com.intellij.ui.components.JBScrollPane;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.Serial;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class FlutterAssetsImagesWindow implements ToolWindowFactory {

    private Project project;
    private ToolWindow toolWindow;

    private String imagesPath = "assets/images";

    private JPanel leftPanel; // 左侧面板
    private JPanel rightPanel; // 右侧面板
    private DefaultListModel<String> groupListModel; // 左侧列表模型
    private ArrayList<AssetsGroupIcons> groups; // 数据源
    private Integer selectedIndex = 0;

    private Integer iconWidth = 80;

    private JPanel mainPanel;
    private JBScrollPane rightScrollPane;

    private JLabel titleLabel;

    @Override
    public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) {
        this.project = project;
        this.toolWindow = toolWindow;

        initUI();
    }

    /// 初始化UI
    private void initUI() {
        // 主面板，水平布局
        JPanel mainPanel = new JPanel(new BorderLayout());
        this.mainPanel = mainPanel;

        // 左侧面板：显示fileGroupName列表
        leftPanel = new JPanel(new BorderLayout());
        groupListModel = new DefaultListModel<>();
        JBList<String> groupList = new JBList<>(groupListModel);
        groupList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        groupList.setFixedCellWidth(120); // 设置左侧宽度
        groupList.setBackground(JBColor.WHITE);

        // 左侧滚动面板
        JBScrollPane leftScrollPane = (JBScrollPane) ScrollPaneFactory.createScrollPane(groupList);
        leftScrollPane.setBorder(BorderFactory.createEmptyBorder());
        leftPanel.add(leftScrollPane, BorderLayout.CENTER);

        // 右侧面板：显示选中的组的list
        rightPanel = new JPanel(new WrapLayout(FlowLayout.LEADING, 2, 2));

        // 右侧滚动面板
        JBScrollPane rightScrollPane = new JBScrollPane(rightPanel);
        rightScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

        // 主面板布局
        mainPanel.add(leftPanel, BorderLayout.WEST);
        mainPanel.add(rightScrollPane, BorderLayout.CENTER);

        // 顶部面板：刷新按钮
        JPanel topPanel = topPanel();
        mainPanel.add(topPanel, BorderLayout.NORTH);

        // 底部：显示鼠标指向的图片的一些信息
        JPanel titlePanel = hoverPanel();
        mainPanel.add(titlePanel, BorderLayout.SOUTH);

        // 设置工具窗口内容
        toolWindow.getComponent().add(mainPanel);

        // 左侧列表点击事件
        groupList.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                selectedIndex = groupList.getSelectedIndex();
                if (selectedIndex < 0) {
                    selectedIndex = 0;
                }
                refreshRightPanel(groups.get(selectedIndex));
            }
        });
    }

    /// 顶部UI
    public JPanel topPanel() {
        // 水平方向排列，并且从左往右排
        JPanel rowView = new JPanel(new FlowLayout(FlowLayout.LEFT));

        // 刷新按键
        JButton refreshBtn = new JButton("刷新");
        rowView.add(refreshBtn);
        refreshBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                loadData();
            }
        });


        JButton subBtn = new JButton("尺寸-");
        rowView.add(subBtn);
        subBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                iconWidth -= 20;
                if (iconWidth < 40) {
                    iconWidth = 40;
                }
                refreshLeftPanel();
            }
        });

        JButton addBtn = new JButton("尺寸+");
        rowView.add(addBtn);
        addBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                iconWidth += 20;
                if (iconWidth > 140) {
                    iconWidth = 140;
                }
                refreshLeftPanel();
            }
        });


        return rowView;
    }


    /// 显示鼠标hover图片的一些信息
    public JPanel hoverPanel() {
        JPanel rowView = new JPanel(new FlowLayout(FlowLayout.LEFT));
        titleLabel = new JLabel();
        rowView.add(titleLabel);

        return rowView;
    }


    /**
     * 创建形如下面的文本：放在

     ///代码中的所有图片，都从这个类中获取。
     class AppIcons {
        static const String images_navi_123123 = "assets/images/navi/123123.png";
        static const String images_navi_2 = "assets/images/navi/2.png";
        static const String images_tabbar_1 = "assets/images/tabbar/1.png";
     }
     */
    private List<String> autoCreateAppIconsClass(ArrayList<AssetsGroupIcons> groups) throws BadHanyuPinyinOutputFormatCombination {

        List<String> propertyLines = new ArrayList<>();
        propertyLines.add("///代码中的所有图片，都从这个类中获取");
        propertyLines.add("class AppIcons {");

        HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
        for (AssetsGroupIcons group : groups) {
            String groupName = group.fileGroupName;

            Boolean exe = false;
            for (AssetsImagesIcon icon : group.list) {
                String fileName = icon.fileName;
                String fileExt = icon.fileExt;

                String leftFileName = fileName;
                leftFileName = leftFileName.replace(" ","_");
                leftFileName = leftFileName.replace("-","_");
                leftFileName = leftFileName.replace("-","_");
                leftFileName = leftFileName.replace("@","_");
                leftFileName = leftFileName.replace("=","_");
                leftFileName = leftFileName.replace("+","_");
                leftFileName = leftFileName.replace("(","");
                leftFileName = leftFileName.replace(")","");
                leftFileName = leftFileName.replace("（","");
                leftFileName = leftFileName.replace("）","");
                leftFileName = PinyinHelper.toHanYuPinyinString(leftFileName, format,"_",true);
                leftFileName = leftFileName.replace(":","");

                if (!StringUtil.isEmpty(fileName) && !StringUtil.isEmpty(fileExt)) {
                    if (exe == false) {
                        exe = true;
                    }
                    propertyLines.add("\tstatic const String images_" + groupName + "_" + leftFileName + " = \"" + imagesPath + "/" + groupName + "/" + fileName + "." + fileExt + "\";");
                }
            }

            // 取出最后一个元素，最后加后换行
            if (!propertyLines.isEmpty() && exe) {
                int index = propertyLines.size() - 1;
                String lastRow = propertyLines.get(index);
                lastRow = lastRow + "\n";
                propertyLines.remove(index);
                propertyLines.add(lastRow);

            }
        }

        propertyLines.add("}");
        return propertyLines;
    }

    private void loadData() {
        String basePath = project.getBasePath() + "/";

        // 获取 assets/images/ 目录下的所有子目录
        VirtualFile assetsDir = project.getBaseDir().findFileByRelativePath(imagesPath);
        VirtualFile[] subDirs = assetsDir.getChildren();

        ArrayList<String> images = virtualFileToPaths(subDirs);
        ArrayList<AssetsImagesIcon> icons = convertToAssetsImagesIcon(images);

        groups = convertToAssetsGroupIcons(icons);

        // 刷新左侧列表
        refreshLeftPanel();

        // 在指定文件夹下创建代码：
        try {
            List<String> appIconLines = autoCreateAppIconsClass(groups);

            VirtualFile iconsFilePath2 = PathUtil.getVirtualIfNotCreateFile(basePath + "lib/","AppIcons.dart");
            //写操作放在这个里面
            ApplicationManager.getApplication().runWriteAction(new Runnable() {
                @Override
                public void run() {
                    // 这里放置需要执行的写操作
                    boolean write = ReadFileUtil.write(iconsFilePath2, appIconLines);
                    if (write) {
                        //弹出弹窗，放在这个里面
                        ApplicationManager.getApplication().invokeLater(() -> {
                            Messages.showInfoMessage(project, "AppIcons.dart 更新成功！", "提示");
                        });
                    } else {
                        //弹出弹窗，放在这个里面
                        ApplicationManager.getApplication().invokeLater(() -> {
                            Messages.showInfoMessage(project, "AppIcons.dart 更新失败！", "提示");
                        });
                    }
                }
            });


        } catch (BadHanyuPinyinOutputFormatCombination e) {
            Messages.showInfoMessage(project, "Warn: 请检查本地的图片名称，尽量使用变量名命名范围", "操作失败");

        }

    }


    /// 刷新左侧列表
    private void refreshLeftPanel() {
        groupListModel.clear();
        for (AssetsGroupIcons group : groups) {
            groupListModel.addElement(group.fileGroupName);
        }

        // 默认选中第一个组
        if (!groups.isEmpty()) {
            refreshRightPanel(groups.get(selectedIndex));
        }
    }

    /// 刷新右侧面板
    private void refreshRightPanel(AssetsGroupIcons group) {
        rightPanel.removeAll(); // 清空右侧面板

        // 添加组内的文件图标
        for (AssetsImagesIcon icon : group.list) {
            // 加载图片
            ImageIcon imageIcon = new ImageIcon(icon.fileFullPath);
            Image image = imageIcon.getImage();
            int width = image.getWidth(null);
            int height = image.getHeight(null);

            int w = 0;
            int h = 0;
            if (width >= height) {
                // 以宽来计算
                w = iconWidth;
                h = w * height / width;
            } else {
                // 以高来计算
                h = iconWidth;
                w = h * width / height;
            }

            Image scaledImage = imageIcon.getImage().getScaledInstance(w, h, Image.SCALE_SMOOTH);

            JLabel iconLabel = new JLabel(new ImageIcon(scaledImage));
            iconLabel.setOpaque(true);
            iconLabel.setBackground(JBColor.LIGHT_GRAY);
            iconLabel.setBorder(BorderFactory.createLineBorder(JBColor.GRAY, 1));

            // 添加鼠标悬停事件监听器
            iconLabel.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseEntered(MouseEvent e) {
                    titleLabel.setText(icon.fileGroupName + " : " + icon.fileNameFull);
                }
            });

            rightPanel.add(iconLabel);
        }

        rightPanel.revalidate(); // 刷新布局
        rightPanel.repaint(); // 重绘面板

        // 粗略重新计算一下宽高
        int width = mainPanel.getWidth() - leftPanel.getWidth();
        int count = width / iconWidth;
        int rowNum = (group.list.size() / count) + 1 + 4;
        rightPanel.setPreferredSize(new Dimension(10, iconWidth * rowNum));

    }

    /// 返回subDirs目录下的文件路径
    private ArrayList<String> virtualFileToPaths(VirtualFile[] subDirs) {
        ArrayList<String> filePaths = new ArrayList<>();
        for (VirtualFile dir : subDirs) {
            collectFilePaths(dir, filePaths);
        }
        return filePaths;
    }

    /// 递归收集文件路径
    private void collectFilePaths(VirtualFile file, ArrayList<String> filePaths) {
        if (file.isDirectory()) {
            // 如果是目录，递归遍历子文件
            for (VirtualFile child : file.getChildren()) {
                collectFilePaths(child, filePaths);
            }
        } else {
            // 如果是文件，将路径添加到列表中
            filePaths.add(file.getPath());
        }
    }

    /// 将ArrayList<String>转换为ArrayList<AssetsImagesIcon>
    private ArrayList<AssetsImagesIcon> convertToAssetsImagesIcon(ArrayList<String> filePaths) {
        ArrayList<AssetsImagesIcon> assetsImagesIcons = new ArrayList<>();
        for (String filePath : filePaths) {
            AssetsImagesIcon icon = new AssetsImagesIcon();
            icon.fileFullPath = filePath; // 设置全路径

            File file = new File(filePath);

            icon.fileNameFull = file.getName(); // 设置文件名
            icon.fileName = icon.fileNameFull.substring(0, icon.fileNameFull.lastIndexOf('.')); // 获取文件名（不带后缀）
            icon.fileExt = icon.fileNameFull.substring(icon.fileNameFull.lastIndexOf('.') + 1); // 获取文件后缀

            // 获取文件组名（目录名称）
            File parentFile = file.getParentFile();
            if (parentFile != null) {
                icon.fileGroupName = parentFile.getName();
            } else {
                icon.fileGroupName = "Unknown"; // 如果父目录为空，设置为"Unknown"
            }

            assetsImagesIcons.add(icon);
        }
        return assetsImagesIcons;
    }

    /// 将ArrayList<AssetsImagesIcon>转换为ArrayList<AssetsGroupIcons>
    private ArrayList<AssetsGroupIcons> convertToAssetsGroupIcons(ArrayList<AssetsImagesIcon> assetsImagesIcons) {
        // 使用HashMap按fileGroupName分组
        HashMap<String, AssetsGroupIcons> groupMap = new HashMap<>();

        for (AssetsImagesIcon icon : assetsImagesIcons) {
            String groupName = icon.fileGroupName;

            // 如果组不存在，创建一个新的组
            if (!groupMap.containsKey(groupName)) {
                AssetsGroupIcons group = new AssetsGroupIcons();
                group.fileGroupName = groupName;
                group.list = new ArrayList<>();
                groupMap.put(groupName, group);
            }

            // 将当前icon添加到对应的组中
            groupMap.get(groupName).list.add(icon);
        }

        // 将HashMap中的值转换为ArrayList
        return new ArrayList<>(groupMap.values());
    }
}


class AssetsGroupIcons {
    /// 文件组名
    String fileGroupName;

    ArrayList<AssetsImagesIcon> list;
}

class AssetsImagesIcon {
    /// 全路径
    String fileFullPath;

    /// 文件组名：文件所在的目录名称
    String fileGroupName;

    /// 文件名 带后缀
    String fileNameFull;

    /// 文件名
    String fileName;

    /// 后缀
    String fileExt;

}

class WrapLayout extends FlowLayout {
    @Serial
    private static final long serialVersionUID = 1L;

    public WrapLayout() {
        super();
    }

    public WrapLayout(int align) {
        super(align);
    }

    public WrapLayout(int align, int hgap, int vgap) {
        super(align, hgap, vgap);
    }

    @Override
    public Dimension preferredLayoutSize(Container target) {
        synchronized (target.getTreeLock()) {
            int width = target.getWidth();
            if (width == 0) {
                width = Integer.MAX_VALUE;
            }

            int x = 0;
            int y = 0;
            int rowHeight = 0;

            for (Component component : target.getComponents()) {
                if (component.isVisible()) {
                    Dimension dimension = component.getPreferredSize();
                    if (x + dimension.width > width) {
                        x = 0;
                        y += rowHeight + getVgap();
                        rowHeight = 0;
                    }
                    x += dimension.width + getHgap();
                    rowHeight = Math.max(rowHeight, dimension.height);
                }
            }

            return new Dimension(width, y + rowHeight);
        }
    }
}